import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/**
 * @author jyh
 */
public class DataGenerate {

    private static final int THREAD_COUNT = Runtime.getRuntime().availableProcessors();
    private static final int BATCH_SIZE = 10000;
    private static final int TOTAL_RECORDS = 10_000_000;

    public static void main(String[] args) throws InterruptedException {
        long startTime = System.currentTimeMillis();
        ExecutorService executorService = Executors.newFixedThreadPool(THREAD_COUNT);
        for (int i = 1; i <= THREAD_COUNT; i++) {
            final int tn = i;
            executorService.execute(() -> insertData(tn));
        }
        executorService.shutdown();
        // 阻塞线程池至任务执行完
        executorService.awaitTermination(Long.MAX_VALUE, TimeUnit.SECONDS);
        long endTime = System.currentTimeMillis();
        System.out.println("Total time " + (endTime - startTime) / 1000 + " seconds");
    }

    public static void insertData(int threadNum) {
        try (Connection connection = DriverManager.getConnection(DataSourceConfig.URL, DataSourceConfig.USER, DataSourceConfig.PASS)) {
            // 关闭事务自动提交
            connection.setAutoCommit(false);
            int start = threadNum * BATCH_SIZE + 1;
            int end = start + TOTAL_RECORDS / THREAD_COUNT ;

            String sql = "insert into person(name, age, address) values(?, ?, ?)";
            try (PreparedStatement preparedStatement = connection.prepareStatement(sql)) {

                for (int i = start ; i < end; i++) {
                    preparedStatement.setString(1, "Name_" + i);
                    preparedStatement.setInt(2, i % 2 == 0 ? 0 : 1);
                    preparedStatement.setString(3, "上海市浦东新区广兰路" + i + "号");
                    preparedStatement.addBatch();

                    if (i % BATCH_SIZE == 0) {
                        preparedStatement.executeBatch();
                        connection.commit();
                        System.out.println("Batch insert " + i + " records");
                    }
                }
                // 插入剩余数据
                preparedStatement.executeBatch();
                connection.commit();
            } catch (java.sql.SQLException e) {
                throw new RuntimeException(e);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

}
